package com.sos.core.game.client
{
	
	import com.sos.core.DataObject;
	import com.sos.logging.Dumper;
	import com.sos.logging.IDumpable;
	import com.sos.utils.Utils;
	
	import flash.utils.Dictionary;
	
	/**
	 * 
	 * @author luca tavecchia 
	 */	
	public class GameClientOptions extends DataObject implements IDumpable
	{
		
		// -------------------------------------------------------------------------------
		// CONSTANTS
		// -------------------------------------------------------------------------------
		
		// JSON Property names
		protected const			JSON_PROPERTY_PARAMS:String				= "params";
		
		// Parameters
		public static const		PARAM_GAME_ID:String					= "gameID";
		public static const		PARAM_USER_ID:String					= "userID";
		public static const		PARAM_PASSWORD:String					= "password";
		public static const		PARAM_USER_TOKEN:String					= "userToken";
		public static const		PARAM_GAME_TOKEN:String					= "gameToken";
		
		// Delays & intervals
		private static const	DEFAULT_WORKER_DELAY:uint				= 0100; // 0.1sec
		private static const	DEFAULT_INTERVALL_CONNECTION:uint		= 0250; // 3sec
		private static const	DEFAULT_INTERVALL_HEARTBEAT:uint		= 15000; // 3sec
		private static const	DEFAULT_INTERVALL_HEARTBEAT_RETRY:uint	= 0250; // 3sec
		private static const	DEFAULT_INTERVALL_REQUEST_RETRY:uint	= 1000;	// 1sec
		private static const	DEFAULT_INTERVALL_POLLING:uint			= 1000;	// 1sec
		
		
		// -------------------------------------------------------------------------------
		// FIELDS
		// -------------------------------------------------------------------------------
		
		private var	_workerDelay:uint;
		private var	_intervalConnection:uint;
		private var	_intervalHeartbeat:uint;
		private var	_intervalHeartbeatRetry:uint;
		private var	_intervalPolling:uint;
		private var	_intervalRequestRetry:uint;
		
		private var	_params:Dictionary;
		
		// -------------------------------------------------------------------------------
		// CONSTRUCTOR
		// -------------------------------------------------------------------------------
		
		public function GameClientOptions(data:Object = null)
		{
			// Init objects
			_params = new Dictionary();
			// Clear data
			clear();
			// If data is provided, initializes the instance
			if (data != null) load(data);
		}
		
		// -------------------------------------------------------------------------------
		// PROPERTIES
		// -------------------------------------------------------------------------------
		
		public function get workerDelay():uint
		{
			return _workerDelay;
		}
		
		public function set workerDelay(value:uint):void
		{
			_workerDelay = value;
		}
		
		public function get intervalConnection():uint
		{
			return _intervalConnection;
		}
		
		public function set intervalConnection(value:uint):void
		{
			_intervalConnection = value;
		}
		
		public function get intervalHeartbeat():uint
		{
			return _intervalHeartbeat;
		}
		
		public function set intervalHeartbeat(value:uint):void
		{
			_intervalHeartbeat = value;
		}
		
		public function get intervalHeartbeatRetry():uint
		{
			return _intervalHeartbeatRetry;
		}
		
		public function set intervalHeartbeatRetry(value:uint):void
		{
			_intervalHeartbeatRetry = value;
		}
		
		public function get intervalPolling():uint
		{
			return _intervalPolling;
		}
		
		public function set intervalPolling(value:uint):void
		{
			_intervalPolling = value;
		}
		
		public function get intervalRequestRetry():uint
		{
			return _intervalRequestRetry;
		}
		
		public function set intervalRequestRetry(value:uint):void
		{
			_intervalRequestRetry = value;
		}
		
		// Fixed standard properties
		
		public function get gameID():uint
		{
			return getParamAsUInt(PARAM_GAME_ID);
		}
		
		public function get userID():String
		{
			return getParamAsString(PARAM_USER_ID);
		}
		
		public function get password():String
		{
			return getParamAsString(PARAM_PASSWORD);
		}
		
		public function get params():Array
		{
			var keys:Array = new Array();
			for (var key:String in _params) keys.push(key);
			return keys;
		}
		
		// -------------------------------------------------------------------------------
		// PRIVATE METHODS
		// -------------------------------------------------------------------------------
		
		// DataObject implementation 
		
		override protected function validate(data:Object):void
		{
			if (!data.hasOwnProperty(JSON_PROPERTY_PARAMS)) throwLoadMissingPropError(JSON_PROPERTY_PARAMS);
		}		
		
		override protected function fill(data:Object):void
		{
			// Retrieve raw debug keys
			var raw_params:Object = data[JSON_PROPERTY_PARAMS];
			// Adds all the keys to the params dictionary
			for (var key:String in raw_params)
			{
				setParam(key, raw_params[key]);
			}
		}
		
		// Params handling
		
		protected function clearParams():void
		{
			for (var key:String in _params)
			{
				delete _params[key];
			}
		}
		
		// -------------------------------------------------------------------------------
		// PUBLIC METHODS
		// -------------------------------------------------------------------------------
		
		public function getParam(key:String):Object
		{
			return _params[key];
		}
		
		public function getParamAsString(key:String):String
		{
			return _params[key].toString();
		}
		
		public function getParamAsInt(key:String):int
		{
			return int(_params[key]);
		}
		
		public function getParamAsUInt(key:String):uint
		{
			return uint(_params[key]);
		}
		
		public function setParam(key:String, value:Object):void
		{
			_params[key] = value;
		}
		
		public function hasParam(debugKey:String):Boolean
		{
			return _params[debugKey] != null;
		}
		
		public function equals(options:GameClientOptions):Boolean
		{
			if (this === options) return true;
			return 	_workerDelay			== options.workerDelay && 
					_intervalConnection		== options.intervalConnection && 
					_intervalHeartbeat		== options.intervalHeartbeat && 
					_intervalHeartbeatRetry	== options.intervalHeartbeatRetry &&
					_intervalRequestRetry	== options.intervalRequestRetry &&
					_intervalPolling		== options.intervalPolling &&
					Utils.dictionaryEquals(_params, options._params);
		}
		
		override public function clear():void
		{
			_workerDelay			= DEFAULT_WORKER_DELAY;
			_intervalConnection		= DEFAULT_INTERVALL_CONNECTION;
			_intervalHeartbeat		= DEFAULT_INTERVALL_HEARTBEAT;
			_intervalHeartbeatRetry	= DEFAULT_INTERVALL_HEARTBEAT_RETRY;
			_intervalRequestRetry	= DEFAULT_INTERVALL_REQUEST_RETRY;
			_intervalPolling		= DEFAULT_INTERVALL_POLLING;
			// Clear parameters
			clearParams();
		}
		
		public function dump(source:Array = null, indentDepth:int = 0):Array
		{
			return Dumper.dump(this, null, source, indentDepth);
		}
		
	}
	
}